(function($){
	var Model = {
		curIndex:0,
		anchors:null,
		contentWidth:0,
		contentContainer:null,
		loader:null,
		btnNext:null,
		btnPrevious:null,
		btnFinish:null
	};
    var _init = function(options,$this){
		Model.curIndex = options.selected;
		var container = _initStepFragment.call(this,options,$this);
		var actionBar = _initActionBar.call(this,options,$this);
		var as = _initAnchors.call(this,options,$this);
         $this.append(container);
         $this.append(actionBar); 
		 

		 Model.contentWidth = container.width();

		 if(!options.enableAllSteps){
    		 as.removeClass("selected").removeClass("done").addClass("disabled"); 
    		 as.attr("done",0);
         }else{
        	 as.removeClass("selected").removeClass("disabled").addClass("done"); 
             as.attr("done",1); 
         }
    	
		as.each(function(i){
    		 $($(this).attr("href"), $this).hide();
    		 $(this).attr("rel",i+1);
    	});
		_doStep.call(this,Model.curIndex);
    };

	var _initStepFragment = function(options,$this){
    	var fragments =$this.children('div').addClass("content");
    	var container = $("<div class='stepContainer'>").append(fragments);
    	Model.contentContainer = container;
    	return container;
    };
    var _initAnchors = function(options,$this){
    	var as = $("ul > li > a[href^='#step-']", $this);
		$this.children('ul').addClass("anchor");
    	var _this = this;
    	 //初始化点击事件
    	as.bind("click", function(e){
    		 var nextIndex = as.index(this);
             if(nextIndex == Model.curIndex){
               return false;
             }
             var done = as.eq(nextIndex).attr("done");
             if(done == 1){
            	 _doStep.call(_this,nextIndex);
             }
             return false;
         });
		 Model.anchors = as;
		 return as;
    };
    
    var _initActionBar = function(options,$this){
    	var actionBar = $("<div class='actionBar'>");
    	
    	var loader = $("<div class='loader'>").text("保存中");
    	var _this = this;
		var opt = this.opt;
    	var btnNext = $("<a href='#' class='buttonNext'>").text(opt.labelNext).click(function(){
    		if ($(this).hasClass('buttonDisabled')){
    			return false;
    		}
    		_doNext.call(_this);
    		return false;
    	});
    	var btnPrevious = $("<a href='#' class='buttonPrevious'>").text(opt.labelPrevious).click(function(){
    		if ($(this).hasClass('buttonDisabled')){
    			return false;
    		}
    		_doPrevious.call(_this);
    		return false;
    	});
    	var btnFinish = $("<a href='#' class='buttonFinish'>").text(opt.labelFinish).click(function(){
    		if ($(this).hasClass('buttonDisabled')){
    			return false;
    		}
    		_doFinish.call(_this);
    		return false;
    	});
    	
    	//增加自定义按钮
		$.each(opt.buttons,function(i,b){
			actionBar.append($(b));
		});
		
		if (options.includeFinishButton){
			actionBar.append(btnFinish);
		}
		
		actionBar.append(loader);
		actionBar.append(btnNext).append(btnPrevious);
    	Model.loader = loader;
    	Model.btnNext = btnNext;
    	Model.btnPrevious = btnPrevious;
    	Model.btnFinish = btnFinish;
		return actionBar;
    };
    

    
    var _doStep = function(index){
    	//onLeave
    	this.showLoading();
    	var curIndex = Model.curIndex;
    	var curStep = Model.anchors.eq(curIndex);
    	var opt = this.opt;
    	//1.验证是否跳转页面切换页面
    	if (curIndex != index){
			if (opt.onLeaveBefore != $.noop && !opt.onLeaveBefore.call(this,curIndex,curStep)){
				this.hideLoading();
				return false;
			}
    	}
    	//2.跳转页面
    	var step = Model.anchors.eq(index);
    	//获取data-ajax
    	var data = step.data();
    	var url = data.url;
        var hasContent =  step.data('hasContent');
        var stepNum = index + 1;
        if(url){
           var cache = (data.cache == undefined) ? opt.contentCache : data.cache;
           if(cache && hasContent || index == opt.defaultStep){
        	   _showStep.call(this,index);
           }else{
        	   var _this = this;
        	   var $this = this.$this;
        	   $.ajax({
                   type: "GET",
                   url: url,
                   dataType: "text",
                   success: function(r){
                	   if (r){
            				 step.data("hasContent",true);
            				 $(step.attr("href"), $this).html(r);
            				 _showStep.call(_this,index);    
            			 }
                   },
                   error:function(){
          			   _this.hideLoading();
          		   }
               });
          }
        }else{
        	_showStep.call(this,index);
        }
    };
    
    var _showStep = function(index){
    	var opt = this.opt;
    	var container = Model.contentContainer;
    	var curIndex = Model.curIndex;
    	var step = Model.anchors.eq(index);
    	var curStep = Model.anchors.eq(curIndex);
    	var $this = this.$this;
    	var fragment = $(step.attr("href"), $this);
    	var curFragment = $(curStep.attr("href"), $this);
        if (opt.updateHeight)
			container.height(fragment.outerHeight()); 
        	//container.height(fragment.outerHeight()); 
        var animate = opt.transitionEffect;
        
        var contentWidth = Model.contentWidth;
        var _this = this;
        var aniateCallback = function(){
        	Model.curIndex = index;

        	curStep.removeClass("selected");
        	curStep.addClass("done");
            
        	step.removeClass("disabled");
        	step.removeClass("done");
        	step.addClass("selected");
        	step.attr("done",1);
            _adjustButton.call(_this);
            opt.onLeaveAfter.call(_this,curIndex,curStep);
            opt.onShow.call(_this,index,step);
        };
        if(animate == 'slide'){
        	curFragment.slideUp("fast",function(e){
        		fragment.slideDown("fast");
        		aniateCallback.call();
        	});
        } else if(animate == 'fade'){
        	curFragment.fadeOut("fast",function(e){
        		fragment.fadeIn("fast");
        		aniateCallback.call();
        	});
        } else if(animate == 'slideleft'){
            var nextElmLeft = 0;
            var curElementLeft = 0;
            if(index > curIndex){
                nextElmLeft1 = contentWidth + 10;
                nextElmLeft2 = 0;
                curElementLeft = 0 - curFragment.outerWidth();
            } else {
                nextElmLeft1 = 0 - fragment.outerWidth() + 20;
                nextElmLeft2 = 0;
                curElementLeft = 10 + curFragment.outerWidth();
            }
            if(index == curIndex){
                nextElmLeft1 = fragment.outerWidth() + 20;
                nextElmLeft2 = 0;
                curElementLeft = 0 - curFragment.outerWidth();                           
            }else{
            	curFragment.animate({left:curElementLeft},"fast",function(e){
            		curFragment.hide();
                });                       
            }

            fragment.css("left",nextElmLeft1);
            fragment.show();
            fragment.animate({left:nextElmLeft2},"fast",function(e){
            	aniateCallback.call();                   
            });
        } else{
        	curFragment.hide(); 
			fragment.show();
            aniateCallback.call();   
        }
        this.hideLoading();
    };
    
    var _adjustButton = function(){
    	var opt = this.opt;
    	var curIndex = Model.curIndex;
    	var btnPrevious = Model.btnPrevious;
    	var btnNext = Model.btnNext;
    	var btnFinish = Model.btnFinish;
    	var stepCount = Model.anchors.length;
    	if (!opt.cycleSteps){
    		if (0 >= curIndex){
    			btnPrevious.addClass("buttonDisabled");
    		} else {
    			btnPrevious.removeClass("buttonDisabled");
    		}
    		if (stepCount - 1 <= curIndex){
    			btnNext.addClass("buttonDisabled");
    		}else {
    			btnNext.removeClass("buttonDisabled");
    		}
    	}
    	
    	if (Model.anchors.hasClass('disabled') || opt.enableFinishButton){
    		btnFinish.removeClass("buttonDisabled");
    	} else {
    		btnFinish.addClass("buttonDisabled");
    	}
    };
    
    var _doNext = function(){
    	var nextIndex = Model.curIndex + 1;
    	var stepCount = Model.anchors.length;
    	var opt = this.opt;
    	if (stepCount <= nextIndex){
    		if (!opt.cycleSteps){
    			return false;
    		}
    		nextIndex = 0;
    	}
    	_doStep.call(this,nextIndex);
    };
    
    var _doPrevious = function(){
    	var preIndex = Model.curIndex - 1;
    	if (0 > preIndex){
    		if (!opt.cycleSteps){
    			return false;
    		}
    		preIndex =  Model.anchors.length;
    	}
    	_doStep.call(this,preIndex);
    };

    var _doFinish = function(){
    	this.showLoading();
    	var curIndex = Model.curIndex;
    	var curStep = Model.anchors.eq(curIndex);
    	var opt = this.opt;
    	opt.onFinish != $.noop && opt.onFinish(curIndex,curStep);
    };
    
    var Wizard = function($this,options){
    	var opt = $.extend({}, $.fn.wizard.defaults, options);
    	this.opt = opt;
    	this.$this = $this;
    	_init.call(this,opt,$this);
    };
    Wizard.prototype.showLoading = function(){
    	Model.loader.show();
    };
    Wizard.prototype.hideLoading = function(){
    	Model.loader.hide();
    };
    
    Wizard.prototype.getCurIndex = function(){
    	return Model.curIndex;
    };
    
    Wizard.prototype.getCurStep = function(){
    	var curIndex = this.getCurIndex();
    	var step = Model.anchors.eq(curIndex);
    	return step;
    };
    
    Wizard.prototype.updateHeight = function(){
    	var opt = this.opt;
    	var container = Model.contentContainer;
    	var index = Model.curIndex;
    	var step = Model.anchors.eq(index);
    	var $this = this.$this;
    	var fragment = $(step.attr("href"), $this);
		container.height(fragment.outerHeight()); 
    };
    $.fn.wizard = function(options) {
    	if (this.data("wizard_plugin")){return this.data('wizard_plugin'); }
		var wizard = new Wizard(this,options);
		this.data('wizard_plugin', wizard);
        return wizard;
    };
    
 
    // Default Properties and Events
    $.fn.wizard.defaults = {
          selected: 0,  // Selected Step, 0 = first step   
          enableAllSteps: false,
          updateHeight: true,
          transitionEffect: 'fade', // Effect on navigation, none/fade/slide/slideleft
          contentCache:true, // cache step contents, if false content is fetched always from ajax url
          cycleSteps: false, // cycle step navigation
          includeFinishButton: true, // whether to show a Finish button
          enableFinishButton: true, // make finish button enabled always
          labelNext:'下一步',
          labelPrevious:'上一步',
          labelFinish:'完成',          
          onLeaveBefore: $.noop, // triggers when leaving a step
          onLeaveAfter:$.noop,
          onShow: $.noop,  // triggers when showing a step
          onFinish: $.noop,  // triggers when Finish button is clicked
          buttons:[],
          defaultStep:0
    };    
})(jQuery);
